<?php
/**
 * Library Of Shared Code (LOSC)
 *
 * LICENSE
 *
 * This source file is subject to the New BSD License that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   LOSC Modules
 * @package    User
 * @subpackage Forms
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */

/**
 * User settings form
 *
 * @category   LOSC Modules
 * @package    User
 * @subpackage Forms
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */
class User_Form_User extends Zend_Form
{
    /**
     * User object
     *
     * @var App_User
     */
    private $_user;
    
    /**
     * Injects user object
     *
     * @param App_User $user
     */
    public function setUser(App_User $user)
    {
        $this->_user = $user;
    }
    
    /**
     * Returns user object
     *
     * @return App_User
     * @throws Losc_Exception  if form has no user
     */
    public function getUser()
    {
        if (!$this->_user) {
            throw new Losc_Exception('Form has no user');
        }
        
        return $this->_user;
    }
    
    /**
     * Creates form
     * 
     * @return void
     */
    public function init()
    {
        // call parent for good measure
        parent::init();
        
        // create elements
        $email     = new Zend_Form_Element_Text('email');
        $name      = new Zend_Form_Element_Text('name');
        $nick      = new Zend_Form_Element_Text('nick');
        $birthday  = new Zend_Form_Element_Text('birthday');
        $language  = new Zend_Form_Element_Select('language');
        $locale    = new Zend_Form_Element_Select('locale');
        $timezone  = new Zend_Form_Element_Select('timezone');
        
        $password  = new Zend_Form_Element_Password('newpass');
        $password2 = new Zend_Form_Element_Password('newpass2');
        
        $submit   = new Zend_Form_Element_Submit('save');
        
        // add to form
        $this->addElement($email);
        $this->addElement($name);
        $this->addElement($nick);
        $this->addElement($birthday);
        $this->addElement($language);
        $this->addElement($locale);
        $this->addElement($timezone);
        $this->addElement($password);
        $this->addElement($password2);
        $this->addElement($submit);
        
        $email->setRequired(true)
              ->setLabel('Email')
              ->setAttrib('class', 'text');
        
        $name->setRequired(true)
              ->setLabel('Name')
              ->setAttrib('class', 'text');
        
        $nick->setRequired(true)
              ->setLabel('Nickname')
              ->setAttrib('class', 'text');
        
        $birthday->setRequired(true)
              ->setLabel('Birthday')
              ->setAttrib('class', 'text');
        
        $language->setRequired(true)
              ->setLabel('Language');
        
        $locale->setRequired(true)
              ->setLabel('Locale');
        
        $timezone->setRequired(true)
              ->setLabel('Time zone');
        
        $password->setRequired(false)
                 ->setLabel('New password')
                 ->addValidators(array(
                    new Zend_Validate_StringLength(6, 128),
                    new Zym_Validate_Confirm('newpass2')
                 ));
        
        $password2->setRequired(false)
                  ->setLabel('Confirm password');
        
        $submit->setLabel('Save')
               ->setAttrib('class', 'button')
               ->setOrder(100);
        
        $l = new Zend_Locale('en_US');
        
        $localeList = Zend_Locale::getLocaleList();
        unset($localeList['und_ZZ']);
        
        foreach ($localeList as $key => $value) {
            $l->setLocale($key);
            
            if (!$tempRegion = $l->getRegion()) {
                unset($localeList[$key]);
                continue;
            }
            
            $tempRegion = Zend_Locale::getCountryTranslation($tempRegion);
            $tempLang = Zend_Locale::getLanguageTranslation($l->getLanguage());
            
            $localeList[$key] = $tempRegion . " ($tempLang)";
        }
        asort($localeList);
        $locale->setMultiOptions($localeList);
        
        if (Zend_Registry::isRegistered('Zend_Translate')) {
            $t = Zend_Registry::get('Zend_Translate');
            
            if ($t instanceof Zend_Translate) {
                $t = $t->getAdapter();
            }
            
            if ($t instanceof Zend_Translate_Adapter) {
                foreach ($t->getList() as $key => $value) {
                    if (!$v = $l->getLanguageTranslation($value)) {
                        $temp = new Zend_Locale($value);
                        $v = $l->getLanguageTranslation($temp->getLanguage());
                    }
                    //$language->addMultiOption($value, $key);
                    $language->addMultiOption($key, $v);
                }
            }
        }
        
        $timezone->setMultiOptions($this->getTimezones());
    }
    
    /**
     * Returns an array of time zones suitable for multi options
     *
     * @return array
     */
    public function getTimezones()
    {
        $zones = array();
        $temp = timezone_identifiers_list();
        foreach (timezone_identifiers_list() as $tz) {
            if (!strstr($tz, '/')) {
                continue;
            }
            
            $split = split('/', $tz);
            $region = $split[0];
            $place = $split[1];
            
            if (!isset($zones[$region])) {
                $zones[$region] = array();
            }
            
            $zones[$region][$tz] = $place;
        }
        
        return $zones;
    }

    /**
     * Validate the form
     * 
     * @param  array $data 
     * @return boolean
     */
    public function isValid($data)
    {
        // normalize data
        if ($this->isArray()) {
            $data = $this->_dissolveArrayValue($data,
                                               $this->getElementsBelongTo());
        }
        
        // put data in elements for initial filtering
        $this->populate($data);
        
        // valid if no error exists
        $valid = true;
        
        // get record
        $user = $this->getUser();
        
        $syncFields = array(
            'email', 'name', 'nick', 'birthday', 'language',
            'locale', 'timezone'
        );
        
        foreach ($syncFields as $field) {
            $element = $this->getElement($field);
            $user->$field = $element->getValue();
            $element->setValue($user->$field);
        }
        
        
        if ($newPassword = $this->getValue('newpass')) {
            $newPass = $this->getElement('newpass');
            $confirm = $this->getElement('newpass2');
            
            if ($newPass->isValid($newPassword, $data)) {
                $user->password = md5($newPassword);
            } else {
                $valid = false;
            }
        }
        
        if (!$user->isValid()) {
            foreach ($user->getValidatorMessages() as $key => $messages) {
                $this->getElement($key)->addErrors($messages);
                
            }
            $valid = false;
        }
        
        $this->_errorsExist = !$valid;
        return $valid;
    }
    
    /**
     * Renders form
     *
     * @param Zend_View_Interface $view  [optional]
     */
    public function render(Zend_View_Interface $view = null)
    {
        return str_replace('<dt>&nbsp;</dt>', '<dt></dt>', parent::render($view));
    }
}
